/*
 * 针对 Option(T)的解析，使用`if let` 比`match` 要简洁，并且允许指明数种失败情形下的选项
 */
// 可以用`if let` 匹配任何枚举值
enum Foo {
    Bar,
    Baz,
    Qux(u32),
}

fn main() {
    // 全部是`Option<i32>`类型
    let number = Some(7);
    let letter: Option<i32> = None;
    let emoticon: Option<i32> = None;

    // `if let`结构读作：若`let`将`number` 解构成`Some(i)`，则执行
    // 语句块 `{}`
    if let Some(i) = number {
        println!("Matched {:?}", i);
    }

    // 如果要指明失败情形，就使用 else
    if let Some(i) = letter {
        println!("Matched {:?}", i);
    } else {
        // 解构失败，切换到失败情形
        println!("not matched.");
    }

    // 提供另一种失败情况下的条件
    let i_like_letters = false;
    if let Some(i) = emoticon {
        println!("Matched {:?}", i);
    } else if i_like_letters {
        println!("not match, go with a letter");
    } else {
        // 条件的值为false，于是以下是默认的分支
        println!("I don't like letters. go with emoticon.");
    }

    // 创建变量
    let a = Foo::Bar;
    let b = Foo::Baz;
    let c = Foo::Qux(100);

    // 变量a 匹配到了 Foo::Bar
    if let Foo::Bar = a {
        println!("a is foobar");
    }

    // 变量b 没有匹配到Foo::Bar，什么也不做
    if let Foo::Bar = b {
        println!("b is foobar");
    }

    // 变量c 匹配到了 Foo::Qux, 它带有一个值，和上面Some() 类似
    if let Foo::Qux(v) = c {
        println!("c is {}", v);
    }
}